#include "debug.h"
#include <iostream>

using namespace std;


void SourcePrinter::visitVariableExpr(VariableExpr& expr){
    cout<<"[V:"<<expr.name<<cout<<"] ";
}

void SourcePrinter::visitBinaryExpr(BinaryExpr& expr){
    cout<<expr.left<<" BINOP "<<expr.right;
}

void SourcePrinter::visitVariableDeclare(VariableDeclareStatement& stmt){
    cout<<"[TYPE:"<<stmt.varExpr->name<<stmt.type<<"]: ";

}

void SourcePrinter::visitAssignment(AssignmentStatement& stmt){
    cout<<stmt.lhs<<" = "<<stmt.rhs;
}

void GraphPrinter::indent(){
    int n = tabs;
    while(n--){os << ' ';};
}

void GraphPrinter::beginGraph(string attrs[],int attrNum){
    os<<"digraph G{"<<endl;

    for(int i = 0;i < attrNum;i++){
        indent();
        os<<attrs[i]<<endl;
    }
}

void GraphPrinter::endGraph(){
    os<<"}"<<endl;
}

void GraphPrinter::beginSubgraph(string name,string attrs[],int attrNum){
    PRE = name + '_';
    indent();

    // the *cluster* in dot file can show more clear layout
    // it is recognized by cluster prefix
    os<<"subgraph "<<"cluster_"<<name<<" {"<<endl;
    tabs <<= 1;

    indent();
    os<<"label=\""<<name<<"\";"<<endl;

    for(int i = 0;i < attrNum;i++){
        indent();
        os<<attrs[i]<<endl;
    }
}

void GraphPrinter::endSubgraph(){
    tabs >>= 1;
    indent();
    os<<'}'<<endl;
    PRE = "";
}

void GraphPrinter::newNode(int index,string &label){
    indent();
    os<<PRE<<index<<" [label=\""<<label<<"\"]"<<endl;
}

void GraphPrinter::newLine(int fromIndex,int toIndex){
    indent();
    os<<PRE<<fromIndex<<" -> "<<PRE<<toIndex<<endl;
}

void GraphPrinter::printLine(string str){
    indent();
    os<<str.c_str()<<endl;
}

LogPrinter& operator <<(LogPrinter& log,
        basic_ostream<char,char_traits<char> >&
        (*op)(basic_ostream<char,char_traits<char> > &)){
    if(log.getDebug()){
        (*op)(log.getStream());
    }
    return log;
}

